﻿using UnityEngine;
using UnityEditor;

namespace GameToolkit.Editor
{
    public class QuickGUI
    {
        static Rect cachedViewportRect;
        static Vector2 mousePos;
        static Vector2 mouseDeltaPos;
        static Texture boxTex;

        public delegate bool DrawCallback(int id, int counter);

        public static void SetToggle(string name, bool value)
        {
            EditorPrefs.SetBool(name, value);
        }

        public static bool GetToggle(string name, bool defaultValue = true)
        {
            return EditorPrefs.GetBool(name, defaultValue);
        }

        static Texture2D s_ContrastTex;

        // Returns a usable texture that looks like a high-contrast checker board.
        static Texture2D contrastTexture
        {
            get
            {
                if (s_ContrastTex == null)
                    s_ContrastTex = CreateCheckerTex(
                        new Color(0f, 0.0f, 0f, 0.5f),
                        new Color(1f, 1f, 1f, 0.5f));
                return s_ContrastTex;
            }
        }

        // Create a checker-background texture.
        static Texture2D CreateCheckerTex(Color c0, Color c1)
        {
            Texture2D tex = new Texture2D(16, 16);
            tex.name = "[Generated] Checker Texture";
            tex.hideFlags = HideFlags.DontSave;

            for (int y = 0; y < 8; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c1);
            for (int y = 8; y < 16; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c0);
            for (int y = 0; y < 8; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c0);
            for (int y = 8; y < 16; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c1);

            tex.Apply();
            tex.filterMode = FilterMode.Point;
            return tex;
        }

        public static int TitleBar(string title, int size, FontStyle style, Color color, params string[] moreBtns)
        {
            int defSize = GUI.skin.label.fontSize;
            FontStyle defStyle = GUI.skin.label.fontStyle;
            Color defColor = GUI.skin.label.normal.textColor;

            GUI.skin.label.fontSize = size;
            GUI.skin.label.fontStyle = style;
            GUI.skin.label.normal.textColor = color;

            int ret = -1;

            EditorGUILayout.BeginHorizontal();
            GUI.SetNextControlName("t_" + title);
            bool b = GUILayout.Toggle(true, title, "label", GUILayout.Height(size + 10));
            if (!b)
                ret = 0;
            string dest;
            float width;
            for (int i = 0; i < moreBtns.Length; i++)
            {
                string sty;
                if (moreBtns.Length > 1)
                {
                    sty = i == 0 ? "ButtonLeft" : i == moreBtns.Length - 1 ? "ButtonRight" : "ButtonMid";
                }
                else
                {
                    sty = "button";
                }
                if (!WidthOption(moreBtns[i], out dest, out width))
                {
                    width = 10 + Mathf.Min(30, moreBtns[i].Length * 10);
                }
                bool ok = dest.StartsWith("true:");
                if (ok)
                    dest = dest.Substring(5);
                else if (dest.StartsWith("false:"))
                    dest = dest.Substring(6);
                bool ok2 = GUILayout.Toggle(ok, dest, sty, GUILayout.MaxWidth(width));
                if (ok2 ^ ok && ret == -1)
                    ret = i + 1;
                //if (GUILayout.Button(dest, sty, GUILayout.MaxWidth(width)) && ret == -1)
                //{
                //    ret = i + 1;
                //}
            }


            EditorGUILayout.EndHorizontal();

            GUI.skin.label.fontSize = defSize;
            GUI.skin.label.fontStyle = defStyle;
            GUI.skin.label.normal.textColor = defColor;
            return ret;
        }

        public static int TitleBarWithBtn(string title, int titleSize, int btnSize, params string[] btnStyles)
        {
            int defSize = GUI.skin.label.fontSize;
            FontStyle defStyle = GUI.skin.label.fontStyle;

            GUI.skin.label.fontSize = titleSize;
            GUI.skin.label.fontStyle = FontStyle.Bold;

            int ret = -1;

            EditorGUILayout.BeginHorizontal();
            GUI.SetNextControlName("t_" + title);
            bool b = GUILayout.Toggle(true, title, "label", GUILayout.Height(titleSize + 10));
            if (!b)
                ret = 0;
            for (int i = 0; i < btnStyles.Length; i++)
            {
                bool ok = GUILayout.Button("", btnStyles[i], GUILayout.Width(btnSize));
                if (ok && ret == -1)
                    ret = i + 1;
            }

            EditorGUILayout.EndHorizontal();

            GUI.skin.label.fontSize = defSize;
            GUI.skin.label.fontStyle = defStyle;

            return ret;
        }

        //标题栏,返回按钮索引,0表示标题本身
        public static int TitleBar(string title, int size, params string[] moreBtns)
        {
            int defSize = GUI.skin.label.fontSize;
            FontStyle defStyle = GUI.skin.label.fontStyle;

            GUI.skin.label.fontSize = size;
            GUI.skin.label.fontStyle = FontStyle.Bold;

            int ret = -1;

            EditorGUILayout.BeginHorizontal();
            GUI.SetNextControlName("t_" + title);
            bool b = GUILayout.Toggle(true, title, "label", GUILayout.Height(size + 10));
            if (!b)
                ret = 0;
            string dest;
            float width;
            for (int i = 0; i < moreBtns.Length; i++)
            {
                string sty;
                if (moreBtns.Length > 1)
                {
                    sty = i == 0 ? "ButtonLeft" : i == moreBtns.Length - 1 ? "ButtonRight" : "ButtonMid";
                }
                else
                {
                    sty = "button";
                }
                if (!WidthOption(moreBtns[i], out dest, out width))
                {
                    width = 10 + Mathf.Min(30, moreBtns[i].Length * 10);
                }
                bool ok = dest.StartsWith("true:");
                if (ok)
                    dest = dest.Substring(5);
                else if (dest.StartsWith("false:"))
                    dest = dest.Substring(6);
                bool ok2 = GUILayout.Toggle(ok, dest, sty, GUILayout.MaxWidth(width));
                if (ok2 ^ ok && ret == -1)
                    ret = i + 1;
            }

            EditorGUILayout.EndHorizontal();

            GUI.skin.label.fontSize = defSize;
            GUI.skin.label.fontStyle = defStyle;

            return ret;
        }

        public static int HTabBar(int chosen, int size, int colLimit, params string[] tabs)
        {
            if (tabs == null || tabs.Length == 0)
                return -1;

            int tab = chosen;

            GUIStyle style = "AM ChannelStripHeaderStyle";

            //int defSize = style.fontSize;// GUI.skin.label.fontSize;
            //FontStyle defStyle = style.fontStyle;// GUI.skin.label.fontStyle;
            //Color defColor = style.normal.textColor; // GUI.skin.label.normal.textColor;

            //style.fontSize = size;
            //style.fontStyle = FontStyle.Bold;
            //GUI.skin.label.fontSize = size;
            //GUI.skin.label.fontStyle = FontStyle.Bold;


            int col = colLimit > 0 ? colLimit : tabs.Length;
            int row = tabs.Length / col;
            if (tabs.Length % col > 0)
                row++;
            EditorGUILayout.BeginHorizontal();
            if (row > 1)
            {
                EditorGUILayout.BeginVertical();
                int selectRow = chosen / col;
                for (int r = 0; r < row; r++)
                {
                    if (r == selectRow)
                        continue;
                    EditorGUILayout.BeginHorizontal();
                    for (int c = 0; c < col; c++)
                    {
                        int i = r * col + c;
                        if (i >= tabs.Length)
                            break;
                        //style.normal.textColor = i == chosen ? defColor : defColor * 0.7f;
                        //GUI.skin.label.normal.textColor = i == chosen ? Color.blue : Color.black;
                        //GUI.skin.label.fontStyle = i == chosen ? FontStyle.Bold : FontStyle.Normal;
                        bool b = GUILayout.Toggle(i == chosen, tabs[i], style, GUILayout.Height(size + 10));
                        if (b && i != chosen)
                            tab = i;
                    }
                    EditorGUILayout.EndHorizontal();
                }

                EditorGUILayout.BeginHorizontal();
                for (int c = 0; c < col; c++)
                {
                    int i = selectRow * col + c;
                    if (i >= tabs.Length)
                        break;
                    //style.normal.textColor = i == chosen ? defColor : defColor * 0.7f;
                    //GUI.skin.label.normal.textColor = i == chosen ? Color.blue : Color.black;
                    //GUI.skin.label.fontStyle = i == chosen ? FontStyle.Bold : FontStyle.Normal;
                    bool b = GUILayout.Toggle(i == chosen, tabs[i], style, GUILayout.Height(size + 10));
                    if (b && i != chosen)
                        tab = i;
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();
            }
            else
            {
                for (int i = 0; i < tabs.Length; i++)
                {
                    //style.normal.textColor = i == chosen ? defColor : defColor * 0.7f;
                    //GUI.skin.label.normal.textColor = i == chosen ? Color.blue : Color.black;
                    //GUI.skin.label.fontStyle = i == chosen ? FontStyle.Bold : FontStyle.Normal;
                    bool b = GUILayout.Toggle(i == chosen, tabs[i], style, GUILayout.Height(size + 10));
                    if (b && i != chosen)
                        tab = i;
                }
            }

            EditorGUILayout.EndHorizontal();

            //style.fontSize = defSize;
            //style.fontStyle = defStyle;
            //GUI.skin.label.normal.textColor = defColor;
            //style.normal.textColor = defColor;
            return tab;
        }

        public static void HSeperator()
        {
            Color c = Handles.color;
            Rect r = EditorGUILayout.BeginHorizontal();
            Handles.color = Color.gray;
            Handles.DrawLine(new Vector3(r.xMin, r.yMax - 1), new Vector3(r.xMax, r.yMax - 1));
            Handles.color = Color.white;
            Handles.DrawLine(new Vector3(r.xMin, r.yMax), new Vector3(r.xMax, r.yMax));
            EditorGUILayout.EndHorizontal();
            Handles.color = c;
        }


        public static void HLine(Color color)
        {
            Color c = Handles.color;
            Rect r = EditorGUILayout.BeginHorizontal();
            Handles.color = color;
            Handles.DrawLine(new Vector3(r.xMin, r.yMax), new Vector3(r.xMax, r.yMax));
            EditorGUILayout.EndHorizontal();
            Handles.color = c;
        }

        public static string SearchTextBar(string txt, params GUILayoutOption[] options)
        {
            EditorGUILayout.BeginHorizontal(options);
            string s = GUILayout.TextField(txt, (GUIStyle)"SearchTextField");
            if (GUILayout.Button("", "SearchCancelButton"))
            {
                s = "";
            }
            EditorGUILayout.EndHorizontal();
            return s;
        }

        public static int MultiOptionBar(int selected, string[] titles, params GUILayoutOption[] options)
        {
            return MultiOptionBar(selected, titles, 0, titles.Length, options);
        }

        public static int MultiOptionBar(int selected, string[] titles, int start, int end, params GUILayoutOption[] options)
        {
            int ret = selected;
            EditorGUILayout.BeginHorizontal(options);
            string dest;
            float width;
            for (int i = start; i < end; i++)
            {
                int p = 0x1 << i;
                bool v = (selected & p) != 0;
                bool nv;
                string sty = titles.Length == 1 ? "button" : (i == 0 ? "ButtonLeft" : (i == end - 1 ? "ButtonRight" : "ButtonMid"));
                if (WidthOption(titles[i], out dest, out width))
                    nv = GUILayout.Toggle(v, dest, sty, GUILayout.Width(width));
                else
                    nv = GUILayout.Toggle(v, dest, sty);
                if (nv ^ v)
                {
                    if (nv)
                        ret |= p;
                    else
                        ret &= ~p;
                }
            }
            EditorGUILayout.EndHorizontal();
            return ret;
        }

        public static int GroupButton(string[] texts, params GUILayoutOption[] options)
        {
            int ret = -1;
            EditorGUILayout.BeginHorizontal(options);
            string dest;
            float width;
            for (int i = 0; i < texts.Length; i++)
            {
                string sty = texts.Length == 1 ? "button" : (i == 0 ? "ButtonLeft" : (i == texts.Length - 1 ? "ButtonRight" : "ButtonMid"));
                bool click;
                if (WidthOption(texts[i], out dest, out width))
                    click = GUILayout.Button(dest, sty, GUILayout.Width(width));
                else
                    click = GUILayout.Button(dest, sty);
                if (click)
                {
                    ret = i;
                }
            }
            EditorGUILayout.EndHorizontal();
            return ret;
        }

        static bool WidthOption(string src, out string dest, out float width)
        {
            int n1 = src.IndexOf('<');
            int n2 = n1 >= 0 ? src.IndexOf('>', n1) : 0;
            dest = src;
            width = 0f;
            if (n1 == 0 && n2 > n1 + 1 && float.TryParse(src.Substring(n1 + 1, n2 - n1 - 1), out width))
            {
                dest = src.Substring(n2 + 1);
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// Convenience function that displays a list of sprites and returns the selected value.
        /// </summary>

        static public string DrawList(string field, string[] list, string selection, params GUILayoutOption[] options)
        {
            if (list != null && list.Length > 0)
            {
                int index = 0;
                if (string.IsNullOrEmpty(selection)) selection = list[0];

                // We need to find the sprite in order to have it selected
                if (!string.IsNullOrEmpty(selection))
                {
                    for (int i = 0; i < list.Length; ++i)
                    {
                        if (selection.Equals(list[i], System.StringComparison.OrdinalIgnoreCase))
                        {
                            index = i;
                            break;
                        }
                    }
                }

                // Draw the sprite selection popup
                index = string.IsNullOrEmpty(field) ?
                    EditorGUILayout.Popup(index, list, options) :
                    EditorGUILayout.Popup(field, index, list, options);

                return list[index];
            }
            return null;
        }

        /// <summary>
        /// Draw a distinctly different looking header label
        /// </summary>

        static public bool DrawHeader(string text, string key, bool forceOn)
        {
            bool state = string.IsNullOrEmpty(key) ? forceOn : EditorPrefs.GetBool(key, forceOn);

            GUILayout.Space(3f);
            if (!forceOn && !state) GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f);
            GUILayout.BeginHorizontal();
            GUILayout.Space(3f);

            GUI.changed = false;
#if UNITY_3_5
		if (state) text = "\u25B2 " + text;
		else text = "\u25BC " + text;
		if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) state = !state;
#else
            text = "<b><size=11>" + text + "</size></b>";
            if (state) text = "\u25B2 " + text;
            else text = "\u25BC " + text;
            if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) state = !state;
#endif
            if (GUI.changed && !string.IsNullOrEmpty(key)) EditorPrefs.SetBool(key, state);

            GUILayout.Space(2f);
            GUILayout.EndHorizontal();
            GUI.backgroundColor = Color.white;
            if (!forceOn && !state) GUILayout.Space(3f);
            return state;
        }

        /// <summary>
        /// Begin drawing the content area.
        /// </summary>
        static public void BeginContents(float minHeight)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Space(4f);
            EditorGUILayout.BeginHorizontal("TextArea", GUILayout.MinHeight(minHeight));
            GUILayout.BeginVertical();
            GUILayout.Space(2f);
        }

        /// <summary>
        /// End drawing the content area.
        /// </summary>
        static public void EndContents()
        {
            GUILayout.Space(3f);
            GUILayout.EndVertical();
            EditorGUILayout.EndHorizontal();
            GUILayout.Space(3f);
            GUILayout.EndHorizontal();
            GUILayout.Space(3f);
        }

        static public void ReportView(ref Rect clipRect, Vector2 position, System.Action drawCallback, float height = 300, float grid = 50, string title = "Viewport")
        {
            Rect rect = EditorGUILayout.BeginHorizontal("CurveEditorBackground", GUILayout.Height(height));
            if (rect.width > 1)
            {
                cachedViewportRect = rect;
            }

            clipRect = cachedViewportRect;
            clipRect.xMin += 1;
            clipRect.xMax -= 1;
            clipRect.yMin += 1;
            clipRect.yMax -= 1;

            EditorGUI.BeginDisabledGroup(true);
            GUILayout.Label(title);
            EditorGUI.EndDisabledGroup();

            GUI.BeginClip(clipRect);
            if (grid > 0)
            {
                Handles.color = Color.gray * 0.5f;
                float h = Mathf.Repeat(-position.x, grid);
                while (h < rect.xMax)
                {
                    if (h > 0)
                        Handles.DrawLine(new Vector3(h, 0), new Vector3(h, clipRect.height));
                    h += grid;
                }
                h = Mathf.Repeat(-position.y, grid);
                while (h < rect.yMax)
                {
                    if (h > 0)
                        Handles.DrawLine(new Vector3(0, h), new Vector3(clipRect.width, h));
                    h += grid;
                }
            }

            if (drawCallback != null)
                drawCallback();
            GUI.EndClip();
            EditorGUILayout.EndHorizontal();
        }

        public static bool BeginGroup(string category, bool drop, int space = 5, params GUILayoutOption[] options)
        {
            EditorGUILayout.BeginVertical("helpbox", options);
            EditorGUI.indentLevel++;
            drop = EditorGUILayout.Foldout(drop, category, true, "IN TitleText");
            //EditorGUI.indentLevel--;
            if (drop && space > 0)
                GUILayout.Space(space);
            return drop;
        }

        public static Rect BeginGroupRect(string category, float rightspace, ref bool drop)
        {
            var rect = EditorGUILayout.BeginVertical("helpbox");
            EditorGUILayout.BeginHorizontal();
            EditorGUI.indentLevel++;
            drop = EditorGUILayout.Foldout(drop, category, true, "IN TitleText");
            GUILayout.Space(rightspace);
            EditorGUILayout.EndHorizontal();
            //EditorGUI.indentLevel--;
            return rect;
        }

        public static bool BeginGroup(string category, string subtitle, bool drop)
        {
            var lv = EditorGUI.indentLevel;
            var rect = EditorGUILayout.BeginVertical("helpbox");
            EditorGUI.indentLevel++;
            drop = EditorGUILayout.Foldout(drop, category, true, "IN TitleText");
            //EditorGUI.indentLevel--;
            var label = DevilEditorUtility.EmptyContent;
            label.text = " ";
            EditorGUI.indentLevel = 0;
            var pos = EditorGUI.PrefixLabel(new Rect(rect.x, rect.y + 3, rect.width, 20), label);
            EditorGUI.LabelField(pos, subtitle);
            label.text = "";
            EditorGUI.indentLevel = lv;
            if (drop)
                GUILayout.Space(5);
            return drop;
        }

        public static void EndGroup()
        {
            EditorGUI.indentLevel--;
            EditorGUILayout.EndVertical();
        }

        public static void HandleConvexArrow(Vector3 p0, Vector3 p1, float size, Color color)
        {
            Handles.color = color;
            var dir = p1 - p0;
            var length = dir.magnitude;
            if (length < 0.1f)
                return;
            dir /= length;
            float arrow_scale = 4f;
            var dir2 = Vector3.Cross(Vector3.forward, dir);
            if (length > size * arrow_scale)
            {
                var a = p0 + dir2 * size * 0.5f;
                var b = p0 - dir2 * size * 0.5f;
                var c = b + dir * (length - size * arrow_scale);
                var d = c - dir2 * size * (arrow_scale * 0.5f - 0.5f);
                var e = p1;
                var f = d + dir2 * size * arrow_scale;
                var g = c + dir2 * size;
                Handles.DrawAAConvexPolygon(a, b, c, g);
                Handles.DrawAAConvexPolygon(d, e, f);
            }
            else
            {
                var a = p1 - dir * length - dir2 * length * 0.5f;
                var b = p1;
                var c = a + dir2 * length;
                Handles.DrawAAConvexPolygon(a, b, c);
            }
        }

        // Draws the tiled texture. Like GUI.DrawTexture() but tiled instead of stretched.
        static void DrawTiledTexture(Rect rect, Texture tex)
        {
            float u = rect.width / tex.width;
            float v = rect.height / tex.height;

            Rect texCoords = new Rect(0, 0, u, v);
            TextureWrapMode originalMode = tex.wrapMode;
            tex.wrapMode = TextureWrapMode.Repeat;
            GUI.DrawTextureWithTexCoords(rect, tex, texCoords);
            tex.wrapMode = originalMode;
        }

        // Draw the specified Image.
        public static void DrawSprite(Sprite sprite, Rect drawArea, Color color)
        {
            if (sprite == null)
                return;

            Texture2D tex = sprite.texture;
            if (tex == null)
                return;

            Rect outer = sprite.rect;
            Rect inner = outer;
            inner.xMin += sprite.border.x;
            inner.yMin += sprite.border.y;
            inner.xMax -= sprite.border.z;
            inner.yMax -= sprite.border.w;

            Vector4 uv4 = UnityEngine.Sprites.DataUtility.GetOuterUV(sprite);
            Rect uv = new Rect(uv4.x, uv4.y, uv4.z - uv4.x, uv4.w - uv4.y);
            Vector4 padding = UnityEngine.Sprites.DataUtility.GetPadding(sprite);
            padding.x /= outer.width;
            padding.y /= outer.height;
            padding.z /= outer.width;
            padding.w /= outer.height;

            DrawSprite(tex, drawArea, padding, outer, inner, uv, color, null);
        }

        // Draw the specified Image.
        public static void DrawSprite(Texture tex, Rect drawArea, Rect outer, Rect uv, Color color)
        {
            DrawSprite(tex, drawArea, Vector4.zero, outer, outer, uv, color, null);
        }

        // Draw the specified Image.
        private static void DrawSprite(Texture tex, Rect drawArea, Vector4 padding, Rect outer, Rect inner, Rect uv, Color color, Material mat)
        {
            // Create the texture rectangle that is centered inside rect.
            Rect outerRect = drawArea;
            outerRect.width = Mathf.Abs(outer.width);
            outerRect.height = Mathf.Abs(outer.height);

            if (outerRect.width > 0f)
            {
                float f = drawArea.width / outerRect.width;
                outerRect.width *= f;
                outerRect.height *= f;
            }

            if (drawArea.height > outerRect.height)
            {
                outerRect.y += (drawArea.height - outerRect.height) * 0.5f;
            }
            else if (outerRect.height > drawArea.height)
            {
                float f = drawArea.height / outerRect.height;
                outerRect.width *= f;
                outerRect.height *= f;
            }

            if (drawArea.width > outerRect.width)
                outerRect.x += (drawArea.width - outerRect.width) * 0.5f;

            // Draw the background
            EditorGUI.DrawTextureTransparent(outerRect, null, ScaleMode.ScaleToFit, outer.width / outer.height);

            // Draw the Image
            GUI.color = color;

            Rect paddedTexArea = new Rect(
                outerRect.x + outerRect.width * padding.x,
                outerRect.y + outerRect.height * padding.w,
                outerRect.width - (outerRect.width * (padding.z + padding.x)),
                outerRect.height - (outerRect.height * (padding.w + padding.y))
            );

            if (mat == null)
            {
                GUI.DrawTextureWithTexCoords(paddedTexArea, tex, uv, true);
            }
            else
            {
                // NOTE: There is an issue in Unity that prevents it from clipping the drawn preview
                // using BeginGroup/EndGroup, and there is no way to specify a UV rect...
                EditorGUI.DrawPreviewTexture(paddedTexArea, tex, mat);
            }

            // Draw the border indicator lines
            GUI.BeginGroup(outerRect);
            {
                tex = contrastTexture;
                GUI.color = Color.white;

                if (inner.xMin != outer.xMin)
                {
                    float x = (inner.xMin - outer.xMin) / outer.width * outerRect.width - 1;
                    DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex);
                }

                if (inner.xMax != outer.xMax)
                {
                    float x = (inner.xMax - outer.xMin) / outer.width * outerRect.width - 1;
                    DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex);
                }

                if (inner.yMin != outer.yMin)
                {
                    // GUI.DrawTexture is top-left based rather than bottom-left
                    float y = (inner.yMin - outer.yMin) / outer.height * outerRect.height - 1;
                    DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex);
                }

                if (inner.yMax != outer.yMax)
                {
                    float y = (inner.yMax - outer.yMin) / outer.height * outerRect.height - 1;
                    DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex);
                }
            }

            GUI.EndGroup();
        }
    }
}